import scrapy

class BaseSpider(scrapy.Spider):
    """
    包含自动登录逻辑的基础Spider。
    其他需要登录的Spider可以直接继承此类。
    """
    login_url = 'https://www.example.com/login' # 替换为实际的登录页URL

    # 在settings.py或这里提供您的用户名和密码
    # 更好的做法是从环境变量或配置文件读取
    username = 'your_username'
    password = 'your_password'

    def start_requests(self):
        # 重写start_requests方法，爬虫启动时不再直接请求start_urls，
        # 而是先去请求登录页，并将回调函数指定为self.login
        yield scrapy.Request(self.login_url, callback=self.login)

    def login(self, response):
        # 这个方法负责处理登录页的响应，并提交登录表单
        self.log('正在尝试登录...')

        # Scrapy提供了FormRequest，可以方便地提交表单
        # 它会自动寻找HTML中的<form>标签
        # 在formdata字典中提供您的用户名和密码
        # 注意：这里的 'username_field' 和 'password_field' 需要替换成
        # 登录页上输入框实际的 name 属性值
        yield scrapy.FormRequest.from_response(
            response,
            formdata={
                'username_field': self.username,
                'password_field': self.password
            },
            callback=self.check_login_response
        )

    def check_login_response(self, response):
        # 登录请求提交后，检查响应，判断是否登录成功
        # 判断成功的依据有很多种，例如：
        # 1. URL是否跳转到了个人中心页
        # 2. 页面中是否出现了“欢迎您, [你的用户名]”等字样
        # 3. 页面中是否不再出现“登录”按钮

        if "用户名或密码错误" in response.text:
            self.log('登录失败！请检查用户名和密码。')
            return

        self.log('登录成功！准备开始抓取目标页面...')

        # 登录成功后，才开始真正地去爬取start_urls中的页面
        # 这时的请求会自动带上登录成功后获得的Cookie
        for url in self.start_urls:
            yield scrapy.Request(url, callback=self.parse)

    # 警告：子类必须实现自己的parse方法
    def parse(self, response):
        raise NotImplementedError("每个爬虫子类必须实现自己的parse方法")